home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Observable.java < prev    next >
Text File  |  1998-09-22  |  6KB  |  195 lines

  1. /*
  2.  * @(#)Observable.java    1.20 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.util;
  16.  
  17. /**
  18.  * This class represents an observable object, or "data"
  19.  * in the model-view paradigm. It can be subclassed to represent an 
  20.  * object that the application wants to have observed. 
  21.  * <p>
  22.  * An observable object can have one or more observers. After an 
  23.  * observable instance changes, an application calling the 
  24.  * <code>Observable</code>'s <code>notifyObservers</code> method  
  25.  * causes all of its observers to be notified of the change by a call 
  26.  * to their <code>update</code> method. 
  27.  *
  28.  * @author  Chris Warth
  29.  * @version 1.20, 07/01/98
  30.  * @see     java.util.Observable#notifyObservers()
  31.  * @see     java.util.Observable#notifyObservers(java.lang.Object)
  32.  * @see     java.util.Observer
  33.  * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  34.  * @since   JDK1.0
  35.  */
  36. public class Observable {
  37.     private boolean changed = false;
  38.     private Vector obs;
  39.     /* a temporary array buffer, used as a snapshot of the state of
  40.      * current Observers.  We do notifications on this snapshot while
  41.      * not under synchronization.
  42.      */
  43.     private Observer[] arr = new Observer[2];
  44.     /** Construct an Observable with zero Observers */
  45.  
  46.     public Observable() {
  47.     obs = new Vector();
  48.     }
  49.  
  50.     /**
  51.      * Adds an observer to the set of observers for this object. 
  52.      *
  53.      * @param   o   an observer to be added.
  54.      * @since   JDK1.0
  55.      */
  56.     public synchronized void addObserver(Observer o) {
  57.     if (!obs.contains(o)) {
  58.         obs.addElement(o);
  59.     }
  60.     }
  61.  
  62.     /**
  63.      * Deletes an observer from the set of observers of this object. 
  64.      *
  65.      * @param   o   the observer to be deleted.
  66.      * @since   JDK1.0
  67.      */
  68.     public synchronized void deleteObserver(Observer o) {
  69.         obs.removeElement(o);
  70.     }
  71.  
  72.     /**
  73.      * If this object has changed, as indicated by the 
  74.      * <code>hasChanged</code> method, then notify all of its observers 
  75.      * and then call the <code>clearChanged</code> method to 
  76.      * indicate that this object has no longer changed. 
  77.      * <p>
  78.      * Each observer has its <code>update</code> method called with two
  79.      * arguments: this observable object and <code>null</code>. 
  80.      *
  81.      * @see     java.util.Observable#clearChanged()
  82.      * @see     java.util.Observable#hasChanged()
  83.      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  84.      * @since   JDK1.0
  85.      */
  86.     public void notifyObservers() {
  87.     notifyObservers(null);
  88.     }
  89.  
  90.     /**
  91.      * If this object has changed, as indicated by the 
  92.      * <code>hasChanged</code> method, then notify all of its observers 
  93.      * and then call the <code>clearChanged</code> method to indicate 
  94.      * that this object has no longer changed. 
  95.      * <p>
  96.      * Each observer has its <code>update</code> method called with two
  97.      * arguments: this observable object and the <code>arg</code> argument.
  98.      *
  99.      * @param   arg   any object.
  100.      * @see     java.util.Observable#clearChanged()
  101.      * @see     java.util.Observable#hasChanged()
  102.      * @see     java.util.Observer#update(java.util.Observable, java.lang.Object)
  103.      * @since   JDK1.0
  104.      */
  105.     public void notifyObservers(Object arg) {
  106.  
  107.     int size=0;
  108.  
  109.     synchronized (this) {
  110.         /* We don't want the Observer doing callbacks into
  111.          * into arbitrary code while holding its own Monitor.
  112.          * The code where we extract each Observable from 
  113.          * the Vector and store the state of the Observer
  114.          * needs synchronization, but notifying observers
  115.          * does not (should not).  The worst result of any 
  116.          * potential race-condition here is that:
  117.          * 1) a newly-added Observer will miss a
  118.          *   notification in progress
  119.          * 2) a recently unregistered Observer will be
  120.          *   wrongly notified when it doesn't care
  121.          */
  122.         if (!hasChanged())
  123.         return;
  124.         size = obs.size();
  125.         if (size > arr.length) {
  126.         arr = new Observer[size];
  127.         }
  128.         obs.copyInto(arr);
  129.         clearChanged();
  130.     }
  131.  
  132.     for (int i = size -1; i>=0; i--) {
  133.         if (arr[i] != null) {
  134.         arr[i].update(this, arg);
  135.         }
  136.     }
  137.     }
  138.  
  139.     /**
  140.      * Clears the observer list so that this object no longer has any observers.
  141.      *
  142.      * @since   JDK1.0
  143.      */
  144.     public synchronized void deleteObservers() {
  145.     obs.removeAllElements();
  146.     }
  147.  
  148.     /**
  149.      * Indicates that this object has changed. 
  150.      *
  151.      * @since   JDK1.0
  152.      */
  153.     protected synchronized void setChanged() {
  154.     changed = true;
  155.     }
  156.  
  157.     /**
  158.      * Indicates that this object has no longer changed, or that it has 
  159.      * already notified all of its observers of its most recent change. 
  160.      * This method is called automatically by the 
  161.      * <code>notifyObservers</code> methods. 
  162.      *
  163.      * @see     java.util.Observable#notifyObservers()
  164.      * @see     java.util.Observable#notifyObservers(java.lang.Object)
  165.      * @since   JDK1.0
  166.      */
  167.     protected synchronized void clearChanged() {
  168.     changed = false;
  169.     }
  170.  
  171.     /**
  172.      * Tests if this object has changed. 
  173.      *
  174.      * @return  <code>true</code> if the <code>setChanged</code> method
  175.      *          has been called more recently than the <code>clearChanged</code>
  176.      *          method on this object; <code>false</code> otherwise.
  177.      * @see     java.util.Observable#clearChanged()
  178.      * @see     java.util.Observable#setChanged()
  179.      * @since   JDK1.0
  180.      */
  181.     public synchronized boolean hasChanged() {
  182.     return changed;
  183.     }
  184.  
  185.     /**
  186.      * Returns the number of observers of this object.
  187.      *
  188.      * @return  the number of observers of this object.
  189.      * @since   JDK1.0
  190.      */
  191.     public synchronized int countObservers() {
  192.     return obs.size();
  193.     }
  194. }
  195.